Skip to content

fix(tlsn): raise mux max_num_streams to 2048 - #1159

Open
heeckhau wants to merge 1 commit into
mainfrom
fix/mux-max-streams
Open

fix(tlsn): raise mux max_num_streams to 2048#1159
heeckhau wants to merge 1 commit into
mainfrom
fix/mux-max-streams

Conversation

@heeckhau

@heeckhau heeckhau commented Jun 1, 2026

Copy link
Copy Markdown
Member

Problem

MPC preprocessing fails with TooManyStreams on realistic transcript sizes:

INFO  tlsn_verifier_server::verifier: Accepting MPC TLS commitment with max_sent=8192, max_recv=70000
ERROR tlsn_mux::connection::active: maximum number of streams reached
ERROR mpc_tls::follower: error=preprocess error: execution error: context mux error

The mux's default limit is 512 concurrent streams. The threading design opens many more during preprocessing — roughly ~24 streams per TLS record — so a moderately-sized transcript tips it over. The existing integration tests use a smaller config and never reached the limit, so this wasn't caught.

Measurement

Instrumented the pinned mux rev to record peak concurrent streams during the real end-to-end MPC flow:

max_sent max_recv Peak concurrent streams
4096 16384 285
8192 70000 555 (the production failure)

The peak scales with transcript size; 512 sat right in the middle of the realistic range.

Fix

Raise max_num_streams to 2048 (~3.7× the measured peak).

This deliberately stays below 4096: the mux requires max_connection_receive_window >= 256 KiB * max_num_streams, and the default window is 1 GiB. At 2048 the reserved minimum is 512 MiB, leaving a 512 MiB auto-tuning pool so per-stream receive windows can still grow — whereas 4096 would consume the entire window and pin every stream to 256 KiB, hurting throughput. Memory is allocated lazily per opened stream, so the higher ceiling itself costs nothing.

Test

Adds test_session_allows_many_concurrent_streams, which opens 1024 concurrent streams through a session's mux. It fails at the old 512 default and passes with this change.

Follow-up

The peak scales with transcript size. If deployments support substantially larger transcripts than max_recv=70000, both max_num_streams and max_connection_receive_window should be raised together (keeping the window >= 256 KiB * max_num_streams invariant) rather than bumping the stream cap alone.

MPC preprocessing opens roughly ~24 streams per TLS record. The mux
default limit of 512 concurrent streams was exceeded by realistic
transcript sizes, causing preprocessing to fail with `TooManyStreams`:

    ERROR tlsn_mux::connection::active: maximum number of streams reached
    ERROR mpc_tls::follower: error=preprocess error: ... context mux error

Measured peaks (instrumenting the mux at the pinned rev):
  - max_sent=4096,  max_recv=16384 -> 285 streams
  - max_sent=8192,  max_recv=70000 -> 555 streams (the production failure)

Raise the limit to 2048 (~3.7x the measured peak). This stays within the
default 1 GiB connection receive window (which must be >= 256 KiB *
max_num_streams), preserving a 512 MiB stream-window auto-tuning pool, so
throughput is not affected.

Adds a regression test that opens 1024 concurrent streams through a
session's mux, which fails at the old 512 default.
@sinui0

sinui0 commented Jun 1, 2026

Copy link
Copy Markdown
Member

The issue is that the number of streams increases proportional to work, so this is not a robust fix.

Updating TLSNotary to use this change on mpz should address it: ethereum/mpz#403

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants